package mask

import (
	"regexp"
	"strings"

	"gitee.com/gousing/helper/valid"
)

func general(s string) string {
	rs := []rune(s)
	length := len(rs)
	if length < 1 {
		return "-"
	} else if length == 1 {
		return "*"
	}
	var builder strings.Builder
	switch length {
	case 2:
		builder.WriteString(string(rs[0:1]))
		builder.WriteString("*")
	case 3:
		builder.WriteString(string(rs[0:1]))
		builder.WriteString("**")
	case 4:
		builder.WriteString(string(rs[0:1]))
		builder.WriteString("**")
		builder.WriteString(string(rs[3:]))
	case 5:
		builder.WriteString(string(rs[0:1]))
		builder.WriteString("***")
		builder.WriteString(string(rs[4:]))
	case 6:
		builder.WriteString(string(rs[0:1]))
		builder.WriteString("****")
		builder.WriteString(string(rs[5:]))
	case 7:
		builder.WriteString(string(rs[0:2]))
		builder.WriteString("****")
		builder.WriteString(string(rs[5:]))
	default:
		sl := length / 3
		ml := length - sl - sl
		builder.WriteString(string(rs[0:sl]))
		builder.WriteString(strings.Repeat("*", ml))
		builder.WriteString(string(rs[sl+(ml):]))
	}
	return builder.String()
}

// Any 通用字符串脱敏处理方法
func Any(s string) string {
	s = strings.TrimSpace(s)
	if len(s) < 1 {
		return "-"
	} else if len(s) == 1 {
		return "*"
	}
	if len(s) >= 11 {
		// 快速处理国内手机号
		if valid.IsChineseMobile(s) {
			var builder strings.Builder
			// 脱敏手机号，前3位和后4位保持不变，中间部分用星号替换
			pre := len(s) - 11
			builder.WriteString(s[:pre+3])
			builder.WriteString("****")
			builder.WriteString(s[pre+11-4:])
			return builder.String()
		}
	}
	if len(s) >= 5 {
		// 匹配电子邮件地址
		if valid.IsEmail(s) {
			var builder strings.Builder
			ss := strings.Split(s, "@")
			builder.WriteString(Any(ss[0]))
			builder.WriteString("@")
			builder.WriteString(ss[1])
			return builder.String()
		}
	}
	return general(s)
}

// Name 姓名/名称类字符串脱敏处理方法
func Name(s string) string {
	s = strings.TrimSpace(s)
	if len(s) < 1 {
		return "-"
	} else if len(s) == 1 {
		return "*"
	}
	return general(s)
}

// Email 电子邮件类字符串脱敏处理方法
func Email(s string) string {
	s = strings.TrimSpace(s)
	if len(s) < 1 {
		return "-"
	} else if len(s) == 1 {
		return "*"
	}
	// 字符串就是一个电子邮件地址
	if valid.IsEmail(s) {
		ss := strings.Split(s, "@")
		if valid.IsChineseMobile(ss[0]) {
			return Phone(ss[0]) + "@" + ss[1]
		}
		return general(ss[0]) + "@" + ss[1]
	}
	// 字符串中是否含有电子邮件地址
	// 正则表达式匹配电子邮件地址部分，并保留其他部分不变
	pattern := regexp.MustCompile(`[0-9a-z][0-9a-z\-\._]{0,31}@([0-9a-z][0-9a-z\-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}`)
	if match := pattern.FindAllString(s, -1); len(match) > 0 {
		for _, v := range match {
			s = strings.ReplaceAll(s, v, Email(v))
		}
		return s
	}
	return general(s)
}

// Phone 电话号码类字符串脱敏处理方法
func Phone(s string) string {
	s = strings.TrimSpace(s)
	if len(s) < 1 {
		return "-"
	} else if len(s) == 1 {
		return "*"
	}
	// 快速处理国内手机号
	if valid.IsChineseMobile(s) {
		// 脱敏手机号，前3位和后4位保持不变，中间部分用星号替换
		var builder strings.Builder
		pre := len(s) - 11
		builder.WriteString(s[:pre+3])
		builder.WriteString("****")
		builder.WriteString(s[pre+11-4:])
		return builder.String()
	} else if valid.IsInt(s) || valid.IsFloat(s) {
		return general(s)
	}
	// 正则表达式匹配电话号码部分，并保留其他部分不变
	// 假设格式可能包括国家代码、区号（可能带括号或不带括号）、电话号码、分机号
	// 		{"", "-"},
	// 		{"13987171234", "139****1234"},
	//    {"中国人13987171234", "中国人139****1234"},
	// 		{"+86.13987171234", "+86.139****1234"},
	//  	{"+86-13987171234手机号", "+86-139****1234手机号"},
	// 		{"+86 (10) 12345678", "+86 (10) 12****78"},
	// 		{"010-12345678", "010-12****78"},
	//	  {"10-12345678", "10-12****78"},
	//	  {"0871-12345678", "0871-12****78"},
	//	  {"0871-12345678-888", "0871-12****78-888"},
	// 		{"1234567890", "123****890"},
	// 		{"+8610-12345678", "+8610-12****78"},
	// 		{"1234567890123", "1234*****0123"},
	pattern := regexp.MustCompile(`(\+?[0-9]{1,6}[\s\.-]+|\(?[0-9]{2,4}\)?[\s\-])?([0-9]{3,11})`)
	if match := pattern.FindStringSubmatch(s); len(match) > 1 {
		// 脱敏电话号码部分
		old := strings.Join(match[1:], "")
		end := len(match) - 1
		match[end] = Phone(match[end])
		return strings.ReplaceAll(s, old, strings.Join(match[1:], ""))
	}
	return general(s)
}
